home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 November / EnigmA AMIGA RUN 02 (1995)(G.R. Edizioni)(IT)[!][issue 1995-11][Skylink CD].iso / earcd / unix / mp14tar.z / mp14tar / mpack / macnte.c < prev    next >
C/C++ Source or Header  |  1994-06-01  |  12KB  |  493 lines

  1. /* macnTE.c -- TextEdit Utilities for nifty application library
  2.  *
  3.  * (C) Copyright 1990-1993 by Christopher J. Newman
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and its
  7.  * documentation for any purpose is hereby granted without fee, provided that
  8.  * the above copyright notice appear in all copies and that both that
  9.  * copyright notice and this permission notice appear in supporting
  10.  * documentation, and that the name of Christopher J. Newman not be used in
  11.  * advertising or publicity pertaining to distribution of the software without
  12.  * specific, written prior permission.  Christopher J. Newman makes no
  13.  * representations about the suitability of this software for any purpose.  It
  14.  * is provided "as is" without express or implied warranty.
  15.  *
  16.  * CHRISTOPHER J. NEWMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  17.  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
  18.  * SHALL CHRISTOPHER J. NEWMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  19.  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  20.  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  21.  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  22.  * OF THIS SOFTWARE.
  23.  *
  24.  * Author:    Christopher J. Newman
  25.  * Message:    This is a nifty program.
  26.  */
  27.  
  28. #include "macnapp.h"
  29. #ifndef THINK_C
  30. #include <Fonts.h>
  31. #include <Scrap.h>
  32. #include <ToolUtils.h>
  33. #endif
  34.  
  35. #define DOCWIDTH 2047
  36. #define teinfo    ((nate_win *)winp)
  37.  
  38. /* prototypes for private procedures */
  39. static pascal void vscroll(ControlHandle, short);
  40. static pascal void hscroll(ControlHandle, short);
  41.  
  42. /* initialize a premade window as a TextEdit window with options
  43.  */
  44. #ifdef __STDC__
  45. void NATEinit(na_win *winp, long flags, short docwidth, Ptr data, long len)
  46. #else
  47. void NATEinit(winp, flags, docwidth, data, len)
  48.     na_win    *winp;
  49.     long    flags;
  50.     short    docwidth;
  51.     Ptr        data;
  52.     long    len;
  53. #endif
  54. {
  55.     Rect        rtemp, vtemp;
  56.     
  57.     winp->flags = (winp->flags & ~NATE_FLAGS) | flags;
  58.     if (!docwidth)    docwidth = DOCWIDTH;
  59.     teinfo->docwidth = docwidth;
  60.     rtemp = winp->pwin->portRect;
  61.     vtemp = rtemp;
  62.     if (!(flags & NATE_NOHSCROLL)) {
  63.         vtemp.right = vtemp.left + docwidth;
  64.     }
  65.     if (!(flags & NATE_READONLY)) {
  66.         winp->keyp = NATEkeyp;
  67.     }
  68.     if (!(flags & NATE_NOMOUSE)) {    
  69.         winp->mousep = NATEmousep;
  70.         winp->idlep = NATEidlep;
  71.     }
  72.     winp->menup = NATEmenup;
  73.     winp->activep = NATEactivep;
  74.     winp->updatep = NATEupdatep;
  75.     winp->ctrlp = NATEctrlp;
  76.     winp->closep = NATEclosep;
  77.     winp->cursorRgn = NewRgn();
  78.     teinfo->vctrl = teinfo->hctrl = NULL;
  79.     
  80.     TEAutoView(true, teinfo->hTE = TENew(&vtemp, &rtemp));    
  81.     if (len > 0 && data != (Ptr) NULL) {
  82.         TESetText(data, len, teinfo->hTE);
  83.         TESetSelect(0, 0, teinfo->hTE);
  84.     }
  85.     teinfo->lheight = (*teinfo->hTE)->lineHeight;
  86. }
  87.  
  88. /* initialize a new TextEdit window
  89.  */
  90. short NATEinitp(winp, datap)
  91.     na_win *winp;
  92.     long            *datap;
  93. #ifndef THINK_C
  94. #pragma unused (datap)
  95. #endif
  96. {
  97.     NATEinit(winp, winp->flags, 0, NULL, 0);
  98.     
  99.     return (NA_PROCESSED);
  100. }
  101.  
  102. /* set the controls in the TextEdit window correctly
  103.  */
  104. #ifdef __STDC__
  105. void NATEsetscroll(na_win *winp, Boolean moved, Rect *hrect, Rect *vrect)
  106. #else
  107. void NATEsetscroll(winp, moved, hrect, vrect)
  108.     na_win    *winp;
  109.     Boolean            moved;
  110.     Rect    *hrect;
  111.     Rect            *vrect;
  112. #endif
  113. {
  114.     short        vmax, vvalue, hmax, hvalue;
  115.     TEPtr        te = *teinfo->hTE;
  116.     ControlHandle    vctrl, hctrl;
  117.         
  118.  
  119.     vmax = te->nLines + (*(*te->hText + te->teLength - 1) == '\015' ? 1 : 0)
  120.         - (te->viewRect.bottom - te->viewRect.top) / teinfo->lheight;
  121.     hmax = (short) teinfo->docwidth - (te->viewRect.right - te->viewRect.left);
  122.     if (vmax < 0) vmax = 0;
  123.     if (hmax < 0) hmax = 0;
  124.     vvalue = (te->viewRect.top - te->destRect.top) / teinfo->lheight;
  125.     hvalue = te->viewRect.left - te->destRect.left;
  126.     if (!(winp->flags & NATE_NOVSCROLL)) {
  127.         if (teinfo->vctrl == (ControlHandle) NULL) {
  128.             teinfo->vctrl = NewControl(winp->pwin, vrect, "\p", true, vvalue, 0, vmax,
  129.                 scrollBarProc, 0);
  130.             if (winp->pwin != FrontWindow()) HiliteControl(teinfo->vctrl, 255);
  131.         } else {
  132.             if (vvalue < 0) vvalue = 0;
  133.             if (vvalue > vmax) vvalue = vmax;
  134.             SetCtlMax(vctrl = teinfo->vctrl, vmax);
  135.             SetCtlValue(vctrl, vvalue);
  136.             if (moved) {
  137.                 MoveControl(vctrl, vrect->left, vrect->top);
  138.                 SizeControl(vctrl, vrect->right - vrect->left,
  139.                     vrect->bottom - vrect->top);
  140.                 ShowControl(vctrl);
  141.             }
  142.         }
  143.     }
  144.     if (!(winp->flags & NATE_NOHSCROLL)) {
  145.         if (teinfo->hctrl == (ControlHandle) NULL) {
  146.             teinfo->hctrl = NewControl(winp->pwin, hrect, "\p", true, hvalue, 0, hmax,
  147.                 scrollBarProc, 0);
  148.             if (winp->pwin != FrontWindow()) HiliteControl(teinfo->hctrl, 255);
  149.         } else {
  150.             if (hvalue < 0) hvalue = 0;
  151.             if (hvalue > hmax) hvalue = hmax;
  152.             SetCtlMax(hctrl = teinfo->hctrl, hmax);
  153.             SetCtlValue(hctrl, hvalue);
  154.             if (moved) {
  155.                 MoveControl(hctrl, hrect->left, hrect->top);
  156.                 SizeControl(hctrl, hrect->right - hrect->left,
  157.                     hrect->bottom - hrect->top);
  158.                 ShowControl(hctrl);
  159.             }
  160.         }
  161.     }
  162. }
  163.  
  164. /* track procedure for the vertical scroll bar
  165.  */
  166. static pascal void vscroll(ctrl, part)
  167.     ControlHandle    ctrl;
  168.     short                    part;
  169. {
  170.     short        amount, value, max, lh;
  171.     na_win        *winp;
  172.     TEHandle    hTE;
  173.     
  174.     if (part == 0) return;
  175.     winp = * (na_win**) GetWRefCon((*ctrl)->contrlOwner);
  176.     hTE = teinfo->hTE;
  177.     value = ((*hTE)->viewRect.bottom - (*hTE)->viewRect.top) /
  178.         (lh = teinfo->lheight);
  179.     switch (part) {
  180.         case inUpButton:
  181.             amount = -1;
  182.             break;
  183.         case inDownButton:
  184.             amount = 1;
  185.             break;
  186.         case inPageUp:
  187.             amount = - value;
  188.             break;
  189.         case inPageDown:
  190.             amount = value;
  191.             break;
  192.     }
  193.     if ((amount += (value = GetCtlValue(ctrl))) < 0) amount = 0;
  194.     if (amount > (max = GetCtlMax(ctrl))) amount = max;
  195.     SetCtlValue(ctrl, amount);
  196.     TEScroll(0, (value - amount) * lh, hTE);
  197. }
  198.  
  199. /* track procedure for the horizontal scroll bar
  200.  */
  201. static pascal void hscroll(ctrl, part)
  202.     ControlHandle    ctrl;
  203.     short            part;
  204. {
  205.     short        amount, value, max;
  206.     
  207.     if (part) {
  208.         TEHandle hTE = (* (nate_win**) GetWRefCon((*ctrl)->contrlOwner))->hTE;
  209.         
  210.         value = (*hTE)->viewRect.right - (*hTE)->viewRect.left;
  211.         switch (part) {
  212.             case inUpButton:
  213.                 amount = -6;
  214.                 break;
  215.             case inDownButton:
  216.                 amount = 6;
  217.                 break;
  218.             case inPageUp:
  219.                 amount = - value;
  220.                 break;
  221.             case inPageDown:
  222.                 amount = value;
  223.                 break;
  224.         }
  225.         if ((amount += (value = GetCtlValue(ctrl))) < 0) amount = 0;
  226.         if (amount > (max = GetCtlMax(ctrl))) amount = max;
  227.         SetCtlValue(ctrl, amount);
  228.         TEScroll(value - amount, 0, hTE);
  229.     }
  230. }
  231.  
  232. /* activate procedure for TextEdit
  233.  */
  234. #ifdef __STDC__
  235. short NATEactivep(na_win *winp, Boolean on)
  236. #else
  237. short NATEactivep(winp, on)
  238.     na_win    *winp;
  239.     Boolean on;
  240. #endif
  241. {
  242.     if (on) {
  243.         TEActivate(teinfo->hTE);
  244.     } else {
  245.         TEDeactivate(teinfo->hTE);
  246.     }
  247.     
  248.     return (NA_NOTPROCESSED);
  249. }
  250.  
  251. /* Update procedure for textedit window
  252.  */
  253. #ifdef __STDC__
  254. short NATEupdatep(na_win *winp, Boolean newsize)
  255. #else
  256. short NATEupdatep(winp, newsize)
  257.     na_win    *winp;
  258.     Boolean            newsize;
  259. #endif
  260. {
  261.     TEHandle    hTE = teinfo->hTE;
  262.     WindowPtr    window = winp->pwin;
  263.     Rect        prect, vrect, hrect, drect;
  264.     
  265.     prect = window->portRect;
  266.     EraseRect(&prect);
  267.     hrect = vrect = prect;
  268.     vrect.top--;
  269.     hrect.left--;
  270.     vrect.left = ++vrect.right - 16;
  271.     hrect.top = ++hrect.bottom - 16;
  272.     vrect.bottom -= 14;
  273.     hrect.right -= 14;
  274.     InsetRect(&prect, 4, 4);
  275.     prect.right -= 15;
  276.     if (!(winp->flags & NATE_NOHSCROLL)) prect.bottom -= 15;
  277.     prect.bottom -= (prect.bottom - prect.top) % teinfo->lheight;
  278.     if (newsize) {
  279.         drect = (*hTE)->viewRect = prect;
  280.         drect.right = drect.left + (short) teinfo->docwidth;
  281.         (*hTE)->destRect = drect;
  282.         RectRgn(winp->cursorRgn, &prect);
  283.         OffsetRgn(winp->cursorRgn, -window->portBits.bounds.left,
  284.             -window->portBits.bounds.top);
  285.         TECalText(hTE);
  286.         TESelView(hTE);
  287.         if (teinfo->hctrl != (ControlHandle) NULL) HideControl(teinfo->hctrl);
  288.         if (teinfo->vctrl != (ControlHandle) NULL) HideControl(teinfo->vctrl);
  289.     }
  290.     TEUpdate(&prect, hTE);
  291.     if (newsize) NATEsetscroll(winp, true, &hrect, &vrect);
  292.     
  293.     return (NA_NOTPROCESSED);
  294. }
  295.  
  296. /* control processing procedure for TextEdit
  297.  */
  298. #ifdef __STDC__
  299. short NATEctrlp(na_win *winp, Point p, short part, short mods, ControlHandle ctrl)
  300. #else
  301. short NATEctrlp(winp, p, part, mods, ctrl)
  302.     na_win            *winp;
  303.     Point                    p;
  304.     short            part;
  305.     short                    mods;
  306.     ControlHandle    ctrl;
  307. #endif
  308. #ifndef THINK_C
  309. #pragma unused (mods)
  310. #endif
  311. {
  312.     short            value;
  313.     
  314.     if (part) {
  315.         value = GetCtlValue(ctrl);
  316.         switch (part) {
  317.             case inThumb:
  318.                 part = TrackControl(ctrl, p, (ProcPtr) NULL);
  319.                 if (part && (value -= GetCtlValue(ctrl))) {
  320.                     TEHandle    hTE = teinfo->hTE;
  321.                     
  322.                     if (ctrl == teinfo->vctrl) {
  323.                         TEScroll(0, value * teinfo->lheight, hTE);
  324.                     } else if (ctrl == teinfo->hctrl) {
  325.                         TEScroll(value, 0, hTE);
  326.                     }
  327.                 }
  328.                 break;
  329.             
  330.             default:
  331.                 (void) TrackControl(ctrl, p,
  332.                     (ProcPtr) (ctrl == teinfo->vctrl ? vscroll : hscroll));
  333.                 break;
  334.         }
  335.     }
  336.     
  337.     return (NA_PROCESSED);
  338. }
  339.  
  340. /* idle procedure for TextEdit
  341.  */
  342. short NATEidlep(winp)
  343.     na_win    *winp;
  344. {
  345.     TEIdle(teinfo->hTE);
  346.     
  347.     return (NA_PROCESSED);
  348. }
  349.  
  350. /* key press procedure for TextEdit
  351.  */
  352. #ifdef __STDC__
  353. short NATEkeyp(na_win *winp, long c, short mods)
  354. #else
  355. short NATEkeyp(winp, c, mods)
  356.     na_win    *winp;
  357.     long    c;
  358.     short    mods;
  359. #endif
  360. {
  361.     if (!(mods & cmdKey)) {
  362.         ObscureCursor();
  363.         TEKey(c, teinfo->hTE);
  364.         NATEsetscroll(winp, false, (Rect*) NULL, (Rect*) NULL);
  365.     }
  366.     
  367.     return (NA_PROCESSED);
  368. }
  369.  
  370. /* an edit menu handler for TextEdit
  371.  */
  372. #ifdef __STDC__
  373. short NATEmenup(na_win *winp, WORD menuid, WORD itemno)
  374. #else
  375. short NATEmenup(winp, menuid, itemno)
  376.     na_win    *winp;
  377.     WORD    menuid, itemno;
  378. #endif
  379. {
  380.     MenuHandle    mh = GetMHandle(mEdit);
  381.     TEHandle    hTE = teinfo->hTE;
  382.     TEPtr        pte;
  383.     short        status = NA_NOTPROCESSED;
  384.     
  385.     switch (menuid) {
  386.         case 0:
  387.             pte = *hTE;
  388.             if (pte->selStart != pte->selEnd) {
  389.                 EnableItem(mh, iCopy);
  390.                 if (!(winp->flags & NATE_READONLY)) {
  391.                     EnableItem(mh, iCut);
  392.                     EnableItem(mh, iClear);
  393.                 }
  394.             } else {
  395.                 DisableItem(mh, iCopy);
  396.                 if (!(winp->flags & NATE_READONLY)) {
  397.                     DisableItem(mh, iCut);
  398.                     DisableItem(mh, iClear);
  399.                 }
  400.             }
  401.             EnableItem(mh, iSelAll);
  402.             if (!(winp->flags & NATE_READONLY)) {
  403.                 EnableItem(mh, iPaste);
  404.             }
  405.             break;
  406.  
  407.         case mEdit:
  408.             switch (itemno) {
  409.                 case iCut:
  410.                     TECut(hTE);
  411.                     goto DOSCRAP;
  412.                     
  413.                 case iCopy:
  414.                     TECopy(hTE);
  415.                 DOSCRAP:
  416.                     ZeroScrap();
  417.                     TEToScrap();
  418.                     goto EDITDONE;
  419.                     
  420.                 case iPaste:
  421.                     TEFromScrap();
  422.                     TEPaste(hTE);
  423.                     goto EDITDONE;
  424.                     
  425.                 case iClear:
  426.                     TEDelete(hTE);
  427.                     goto EDITDONE;
  428.                 
  429.                 case iSelAll:
  430.                     TESetSelect(0, 32767, hTE);
  431.                     TESelView(hTE);
  432.                 EDITDONE:
  433.                     status = NA_PROCESSED;
  434.                     NATEsetscroll(winp, false, (Rect*) NULL, (Rect*) NULL);
  435.                     break;
  436.             }
  437.         default:
  438.             DisableItem(mh, iSelAll);
  439.             break;
  440.     }
  441.     
  442.     return (status);
  443. }
  444.  
  445. /* mouse procedure for TextEdit
  446.  */
  447. #ifdef __STDC__
  448. short NATEmousep(na_win *winp, Point p, short type, short mods)
  449. #else
  450. short NATEmousep(winp, p, type, mods)
  451.     na_win    *winp;
  452.     Point    p;
  453.     short    type;
  454.     short    mods;
  455. #endif
  456. {
  457.     TEHandle    hTE = teinfo->hTE;
  458.     
  459.     if (!PtInRect(p, &(*hTE)->viewRect)) return (NA_PROCESSED);
  460.     if (type == NA_DOWN1 || type == NA_DOWN2 || type == NA_DOWNN) {
  461.         TEClick(p, mods & shiftKey ? true : false, hTE);
  462.         NAmousetime = TickCount();
  463.         NAlastmouse++;
  464.     }
  465.     
  466.     return (NA_PROCESSED);
  467. }
  468.  
  469. /* close procedure for TextEdit
  470.  */
  471. short NATEclosep(winp)
  472.     na_win    *winp;
  473. {
  474.     TEDispose(teinfo->hTE);
  475.     
  476.     return (NA_CLOSED);
  477. }
  478.  
  479. /* append text at the end of a TextEdit window
  480.  */
  481. void NATEappend(winp, data, len)
  482.     na_win    *winp;
  483.     char    *data;
  484.     long    len;
  485. {
  486.     TEHandle    hTE = ((nate_win*) winp)->hTE;
  487.     
  488.     TESetSelect(32767, 32767, hTE);
  489.     TEInsert(data, len, hTE);
  490.     TESelView(hTE);
  491.     NATEsetscroll(winp, false, (Rect*) NULL, (Rect*) NULL);
  492. }
  493.